package pt.um.jspecput.lib.writer;

import static org.junit.Assert.*;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

import javax.validation.constraints.Pattern;

import org.databene.benerator.anno.InvocationCount;
import org.databene.feed4junit.Feeder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(Feeder.class)
public class TestClassWriterHelperTest {

    private static BufferedWriter writer;
    private static BufferedReader reader;
    private static File file = new File("temp");

    @Before
    public void setUp() throws Exception {
        FileHandler.createFile(file);
        writer = new BufferedWriter(new FileWriter(file));
        reader = new BufferedReader(new FileReader(file));
    }

    @After
    public void tearDown() throws Exception {
        writer.close();
        reader.close();
        file.delete();
    }

    @Test
    @InvocationCount(10)
    public void testOpenPublicClassDeclaration(
            @Pattern(regexp = "[A-Z][A-Za-z0-9]*") String className)
            throws Exception {
        String expected = "@RunWith(Feeder.class)";

        TestClassWriterHelper.openPublicClassDeclaration(writer, className);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "public class " + className + " {";
        assertEquals(expected, reader.readLine());

    }

    @Test
    @InvocationCount(10)
    public void testOpenPublicAbstractClassDeclaration(
            @Pattern(regexp = "[A-Z][A-Za-z0-9]*") String className)
            throws Exception {
        String expected = "@RunWith(Feeder.class)";

        TestClassWriterHelper.openPublicAbstractClassDeclaration(writer, className);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "public abstract class " + className + " {";
        assertEquals(expected, reader.readLine());
    }

    @Test
    @InvocationCount(10)
    public void testOpenPublicFinalClassDeclaration(
            @Pattern(regexp = "[A-Z][A-Za-z0-9]*") String className)
            throws Exception {
        String expected = "@RunWith(Feeder.class)";

        TestClassWriterHelper.openPublicFinalClassDeclaration(writer, className);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "public final class " + className + " {";
        assertEquals(expected, reader.readLine());

    }

    @Test
    @InvocationCount(10)
    public void testOpenClassDeclaration(
            @Pattern(regexp = "[A-Z][A-Za-z0-9]*") String className)
            throws Exception {
        String expected = "@RunWith(Feeder.class)";

        TestClassWriterHelper.openClassDeclaration(writer, className);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "class " + className + " {";
        assertEquals(expected, reader.readLine());

    }

    @Test
    @InvocationCount(10)
    public void testOpenAbstractClassDeclaration(
            @Pattern(regexp = "[A-Z][A-Za-z0-9]*") String className)
            throws Exception {
        String expected = "@RunWith(Feeder.class)";

        TestClassWriterHelper.openAbstractClassDeclaration(writer, className);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "abstract class " + className + " {";
        assertEquals(expected, reader.readLine());
    }

    @Test
    @InvocationCount(10)
    public void testOpenFinalClassDeclaration(
            @Pattern(regexp = "[A-Z][A-Za-z0-9]*") String className)
            throws Exception {
        String expected = "@RunWith(Feeder.class)";

        TestClassWriterHelper.openFinalClassDeclaration(writer, className);
        writer.close();

        assertEquals(expected, reader.readLine());

        expected = "final class " + className + " {";
        assertEquals(expected, reader.readLine());
    }

}
